package com.user.service.impl;

import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.user.repositories.LoginUserRepository;
import com.user.repositories.UserRepository;
import com.user.model.vo.LoginVo;
import com.user.model.vo.UserVo;
import com.user.model.vo.VerificationVo;
import com.user.param.Result;
import com.user.service.UserService;
import com.user.util.CatchUtil;
import com.user.util.ChangeUtil;
import com.user.util.GetUserUtil;
import com.user.util.MD5Util;
import com.user.model.entity.LoginUser;
import com.user.model.entity.User;
import com.user.tool.Base64Tool;
import com.user.enums.LoginStatus;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

@Service
@Slf4j
public class UserServiceImpl implements UserService {


    @Autowired
    DefaultKaptcha defaultKaptcha;

    @Autowired
    UserRepository userRepository;

    @Autowired
    LoginUserRepository loginUserRepository;

    CatchUtil catchUtil = new CatchUtil();

    @Override
    public Result login(LoginVo loginVo, HttpServletResponse response) {

        LoginStatus loginStatus = LoginStatus.otherError;

        //1.验证验证码是否成功
        String verCode = (String) catchUtil.getCatch(loginVo.getVerificationToken());
        if (verCode != null) {
            if (!verCode.equalsIgnoreCase(loginVo.getVerificationCode())) {
                loginStatus = LoginStatus.verificationCodeError;
                return new Result(loginStatus.getStatus(), loginStatus.getName(), null);
            }
        }

        //2.查看是否有该用户
        User user = userRepository.findByPhoneAndDeleted(loginVo.getPhone(),'1');
        if (null == user) {
            loginStatus = LoginStatus.passwordError;
            return new Result(loginStatus.getStatus(), loginStatus.getName(), null);
        }

        LoginUser loginUser = loginUserRepository.findByUserIdAndDeleted(user.getId(),'1');

        if (null == loginUser) {
            loginStatus = LoginStatus.otherError;
            return new Result(loginStatus.getStatus(), loginStatus.getName(), null);
        }

        //3.校验密码

        if (!MD5Util.encryptPassword(loginVo.getPassword()).equals(loginUser.getPassword())) {
            loginStatus = LoginStatus.passwordError;
        } else {
            UUID uuid = UUID.randomUUID();
            String token = uuid.toString();
            token = token.replace("-", "");//替换掉中间的那个横杠
            catchUtil.putCatch(token, user);

            response.setHeader("token", token);
            loginStatus = LoginStatus.success;
            return new Result(loginStatus.getStatus(), loginStatus.getName(), token);

        }

        return new Result(loginStatus.getStatus(), loginStatus.getName(), null);
    }

    public Result logout() {
        log.info("用户退出");
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        String token = request.getHeader("token");
        log.info("用户退出：token：{}",token);

        if (catchUtil.deleteCatch(token)) {
            return new Result(Result.SUCCESS_CODE, "退出成功", null);
        }

        return new Result(Result.ERROR_CODE, "退出失败", null);
    }

    @Override
    public Result getVerificationCode() {

        log.info("生成验证码");
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        // 生成验证码Token
        String captchaToken = UUID.randomUUID().toString();
        //生成文字验证码
        String captchaCode = defaultKaptcha.createText();
        if ("1".equals(MDC.get("MockLogin"))) {
            captchaToken = "token001";
            captchaCode = "A1234";
        }
        log.info("VerificationCodeToken:{},value:{}", captchaToken, captchaCode);
        //生成图片验证码
        BufferedImage image = defaultKaptcha.createImage(captchaCode);
        try {
            ImageIO.write(image, "jpg", baos);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String base64Captcha = Base64Tool.encode(baos.toByteArray());

        //TODO 缓存验证码5分钟
        catchUtil.putCatch(captchaToken, captchaCode, 5 * 60);

        VerificationVo verificationVO = new VerificationVo();
        verificationVO.setToken(captchaToken);
        verificationVO.setValue(base64Captcha);
        return new Result(verificationVO);

    }

    @Override
    @Transactional
    public Result registeredUser(UserVo userVo) {
        log.info("用户注册：{}", userVo);

        User user = new User();
        ChangeUtil.transalte(userVo, user);
        user.setDeleted('1');
        user = userRepository.save(user);
        LoginUser loginUser = new LoginUser();
        loginUser.setPassword(MD5Util.encryptPassword(userVo.getPassword()));
        loginUser.setUserId(user.getId());
        loginUser.setDeleted('1');
        loginUser = loginUserRepository.save(loginUser);
        if (loginUser.getId() != null) {
            return new Result(Result.SUCCESS_CODE, "注册成功", null);
        }
        return new Result(Result.ERROR_CODE, "注册失败", null);
    }

    @Override
    public Result userList() {
        log.info("用户列表：{}");
        List<User> users= userRepository.findAll();
        return new Result(users);
    }

    @Override
    public Result userInfo() {
        log.info("获取用户信息");
        User user = new User();
        user = GetUserUtil.loginUser();
        if (null == user){
            return new Result(null);
        }
        return new Result(user);
    }
}
